package com.example.videoplayer.controller;

import com.example.videoplayer.model.Video;
import com.example.videoplayer.service.HLSConversionService;
import com.example.videoplayer.service.VideoService;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.http.codec.multipart.FilePart;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@CrossOrigin
@RestController
@RequestMapping("/api/videos")
public class VideoController {
    
    private static final Logger logger = LoggerFactory.getLogger(VideoController.class);
    
    @Autowired
    private VideoService videoService;
    @Autowired
    private HLSConversionService hlsConversionService;
    
    @GetMapping("/stream/{fileName}")
    public Mono<ResponseEntity<Resource>> streamVideo(
            @PathVariable String fileName,
            @RequestHeader(value = "Range", required = false) String range) {
        return videoService.streamVideo(fileName, range)
                .retry(3)
                .onErrorResume(e -> Mono.empty());
    }

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<Video> uploadVideo(
            @RequestPart("file") Mono<FilePart> fileMono,
            @RequestPart("title") String title,
            @RequestPart("category") String category,
            @RequestPart("description") String description) {
        
        return fileMono.flatMap(file -> videoService.uploadVideo(file, title, category, description));
    }

    @GetMapping("/hls/{fileName}")
    public Mono<ResponseEntity<String>> getHLSStream(@PathVariable String fileName) {
        return videoService.getHLSStreamUrl(fileName)
            .map(url -> ResponseEntity.ok()
                .contentType(MediaType.TEXT_PLAIN)
                .body(url));
    }

    @GetMapping("/list")
    public Flux<Video> getAllVideos(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "12") int size) {
        return videoService.getAllVideos(page, size);
    }

    @GetMapping("/list/{category}")
    public Flux<Video> getVideosByCategory(
            @PathVariable String category,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "12") int size) {
        return videoService.getVideosByCategory(category, page, size);
    }

    @GetMapping(value = "/categories", produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<ResponseEntity<List<String>>> getAllCategories() {
        return videoService.getAllCategories()
                .map(categories -> {
                    logger.debug("Retrieved categories: {}", categories);
                    return ResponseEntity.ok()
                            .contentType(MediaType.APPLICATION_JSON)
                            .body(categories);
                })
                .defaultIfEmpty(ResponseEntity.ok(Collections.emptyList()));
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<Video>> getVideo(@PathVariable Long id) {
        return videoService.getVideoById(id)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.notFound().build());
    }

    @GetMapping("/conversion-progress/{fileName}")
    public Mono<ResponseEntity<Double>> getConversionProgress(@PathVariable String fileName) {
        if (hlsConversionService.isConversionInProgress(fileName)) {
            return hlsConversionService.getConversionProgress(fileName)
                    .map(progress -> ResponseEntity.ok(progress));
        }
        return Mono.just(ResponseEntity.ok(100.0)); // 如果不在转换中，返回100%
    }
} 